/*
	GameClient.cpp

	This object is used to connect to an GameServer object over a Socket object
	(c)1999 Palestar, Richard Lyle
*/

#define MEDUSA_TRACE_ON			// force trace messages to stay on
#include "Debug/Assert.h"
#include "World/NounTarget.h"

#include "GameClient.h"

//---------------------------------------------------------------------------------------------------

dword GameClient::sm_nVersion = 1.019;

//---------------------------------------------------------------------------------------------------

IMPLEMENT_FACTORY( GameClient, WorldClient );

GameClient::GameClient()
{}

//---------------------------------------------------------------------------------------------------

void GameClient::UserGameClient::onShipDestroyed( Noun * pKiller )
{}

void GameClient::UserGameClient::onShipCaptured( Noun * pCapper )
{}

void GameClient::UserGameClient::onShipDetached()
{}

void GameClient::UserGameClient::onOrderReceived( NounShip::Order order, Noun * pTarget, Noun * pFrom )
{}

//---------------------------------------------------------------------------------------------------

dword GameClient::version() const
{
	return sm_nVersion;
}

bool GameClient::prepWorld()
{
	GameContext * pContext = gameContext();
	if (! pContext )
		return false;
	pContext->setGameUser( this );

	return WorldClient::prepWorld();
}

Noun * GameClient::validateNoun( Noun * pNoun )
{
	if ( WidgetCast<NounTarget>( pNoun ) )
		return pNoun;		// all target noun types are always valid!
	NounGame * pTarget = WidgetCast<NounGame>( WorldClient::validateNoun( pNoun ) );
	if (! pTarget )
		return NULL;
	if (! pTarget->isDetected( factionId() ) )
		return NULL;		// object not detected by the players faction

	return pTarget;
}

//---------------------------------------------------------------------------------------------------

void GameClient::onChat( Noun * pNoun, const char * pMessage )
{
	bool bPushChat = true;

	// ignore chat messages from planets and structures not in our faction...
	if ( (WidgetCast<NounPlanet>( pNoun ) || WidgetCast<NounStructure>( pNoun )) )
		bPushChat = pNoun->factionId() == factionId();

	if ( bPushChat )
		WorldClient::onChat( pNoun, pMessage );
}

void GameClient::onAttachNoun( Noun * pNoun )
{}

void GameClient::onDetachNoun( Noun * pNoun )
{}

//---------------------------------------------------------------------------------------------------

void GameClient::onKill( Noun * pWho, Noun *pDead )
{}

void GameClient::onDestroyed( NounShip * pWho, Noun * pKiller )
{
	pushChat( CharString().format( "<color;ffffff>Comms: %s has been destroyed by %s!", 
		pWho->name(), pKiller != NULL ? pKiller->name() : "?" ) );

	// check if the players ship was destroyed
	if ( pWho != NULL && pWho == m_pSelf )
	{
		// notify the user
		((UserGameClient *)user())->onShipDestroyed( pKiller );
	}
}

void GameClient::onDamageShip( Noun * pWho, float damage, Noun *pTarget )
{}

void GameClient::onCaptureShip( Noun * pWho, NounShip * pCaptured )
{
	if ( pCaptured != NULL && pWho != NULL )
		pushChat( CharString().format( "<color;ffffff>Comms: %s has been captured by the %s (%s)", 
			pCaptured->name(), pWho->teamName(), pWho->name() ) );

	// this is the captured ship ?
	if ( pCaptured != NULL && pCaptured == m_pSelf )	
	{
		// inform user
		((UserGameClient *)user())->onShipCaptured( pWho );
	}
}

void GameClient::onFriendlyFire( Noun * pWho, float damage )
{}

void GameClient::onPlanetsDamaged( Noun * pWho, float damage )
{}

void GameClient::onPlanetsCaptured( Noun * pWho, float amount )
{}

void GameClient::onRepair( Noun * pWho, float repair )
{}

void GameClient::onConstruct( Noun * pWho, float construct )
{}

void GameClient::onKamikaze( Noun * pWho, float damage )
{}

void GameClient::onSelfDestruct( NounShip * pWho )
{
	pushChat( CharString().format( "<color;ffffff>Comms: %s has self-destructed!", pWho->name() ) );

	if ( pWho == m_pSelf )
	{
		// notify user
		((UserGameClient *)user())->onShipDestroyed( pWho );
	}
}

void GameClient::onJump( Noun * pWho )
{}

void GameClient::onCollidePlanet( Noun * pWho )
{}

void GameClient::onResourcesLost( Noun * pWho, float amount )
{}

void GameClient::onScout( Noun * pWho, float points )
{}

void GameClient::onBonusPrestige( Noun * pWho, float bonus )
{}

void GameClient::onCredits( Noun * pWho, int credits )
{}

void GameClient::onOrderReceived( NounShip * pWho, NounShip::Order order, Noun * pTarget, Noun * pFrom )
{
	if ( pWho == self() )
		((UserGameClient *)user())->onOrderReceived( order, pTarget, pFrom );
}

//---------------------------------------------------------------------------------------------------
// EOF
